Many applications have the need to call a specific method during regular intervals of time. For example, you may have an application that needs to display the current time on a status bar via a given helper function. As another example, you may wish to have your application call a helper function every so often to perform noncritical background tasks such as checking for new e-mail messages. For situations such as these, you can use the System.Threading.Timer type in conjunction with a related delegate named TimerCallback.
To illustrate, assume you have a Console Application (TimerApp) that will print the current time every second until the user presses a key to terminate the application. The first obvious step is to write the method that will be called by the Timer type (be sure to import System.Threading into your code file):
class Program { static void PrintTime(object state) { Console.WriteLine("Time is: {0}", DateTime.Now.ToLongTimeString()); } static void Main(string[] args) { } }
Notice how this method has a single parameter of type System.Object and returns void. This is not optional, given that the TimerCallback delegate can only call methods that match this signature. The value passed into the target of your TimerCallback delegate can be any bit of information whatsoever (in the case of the e-mail example, this parameter might represent the name of the Microsoft Exchange server to interact with during the process). Also note that given that this parameter is indeed a System.Object, you are able to pass in multiple arguments using a System.Array or custom class/structure.
The next step is to configure an instance of the TimerCallback delegate and pass it into the Timer object. In addition to configuring a TimerCallback delegate, the Timer constructor allows you to specify the optional parameter information to pass into the delegate target (defined as a System.Object), the interval to poll the method, and the amount of time to wait (in milliseconds) before making the first call, for example:
static void Main(string[] args) { Console.WriteLine("***** Working with Timer type *****\n"); // Create the delegate for the Timer type. TimerCallback timeCB = new TimerCallback(PrintTime); // Establish timer settings. Timer t = new Timer( timeCB, // The TimerCallback delegate object. null, // Any info to pass into the called method (null for no info). 0, // Amount of time to wait before starting (in milliseconds). 1000); // Interval of time between calls (in milliseconds). Console.WriteLine("Hit key to terminate..."); Console.ReadLine(); }
In this case, the PrintTime() method will be called roughly every second and will pass in no additional information to said method. Here is the output:
***** Working with Timer type ***** Hit key to terminate... Time is: 6:51:48 PM Time is: 6:51:49 PM Time is: 6:51:50 PM Time is: 6:51:51 PM Time is: 6:51:52 PM Press any key to continue . . .
If you did wish to send in some information for use by the delegate target, simply substitute the null value of the second constructor parameter with the appropriate information:
// Establish timer settings. Timer t = new Timer(timeCB, "Hello From Main", 0, 1000);
You can then obtain the incoming data as follows:
static void PrintTime(object state) { Console.WriteLine("Time is: {0}, Param is: {1}", DateTime.Now.ToLongTimeString(), state.ToString()); }
Source Code The TimerApp project is included under the Chapter 19 subdirectory.